package com.lonely.order.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.lonely.api.shein.SheinOpenSDK;
import com.lonely.api.shein.config.HttpClientConfig;
import com.lonely.api.shein.http.RequestBuilder;
import com.lonely.api.shein.model.ApiResult;
import com.lonely.api.shein.model.AuthInfo;
import com.lonely.api.shein.model.HttpMethodEnum;
import com.lonely.api.shein.model.SignModeEnum;
import com.lonely.api.shein.service.SheinOpenSDKClient;
import com.lonely.common.annotation.RedisLock;
import com.lonely.common.exception.BusinessException;
import com.lonely.order.domain.dto.api.*;
import com.lonely.order.domain.entity.SysSheinOpenApiSecret;
import com.lonely.order.service.IMesApiService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Objects;

/**
 * mes api接口实现
 *
 * @author fzzf
 */
@Service
@Slf4j
public class MesApiServiceImpl implements IMesApiService {

    private SheinOpenSDKClient api;

    @PostConstruct
    public void setUp() {
        HttpClientConfig config = new HttpClientConfig();
        config.setDomain("https://openapi.sheincorp.cn");
        api = SheinOpenSDK.getInstance(config);
    }

    /**
     * 按时间查询生产制单号
     *
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    @RedisLock(key = "'mesApi:queryProduceOrderIds'", waitTime = 60000)
    public List<Integer> queryProduceOrderIds(SysSheinOpenApiSecret openApiSecret, QueryProduceOrderIdsReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/query-produce-order-ids", reqDTO, SignModeEnum.OPEN_KEY_ID, openApiSecret);
        String response = api.post(requestBuilder);
        System.out.println(response);

        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (Objects.equals(apiResult.getCode(), "0")) {
            return Convert.toList(Integer.class, apiResult.getInfo());
        } else {
            // 调用失败
            log.error("按时间查询生产制单号 接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
    }

    /**
     * MES-FAC-001 订单数据获取接口
     *
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    public List<GetOrderInfoResDTO> getOrderInfo(SysSheinOpenApiSecret sheinOpenApiSecret, GetOrderInfoReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/get-order-info", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("MES-FAC-001 订单数据获取接口 接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.toList(GetOrderInfoResDTO.class, apiResult.getInfo());
    }

    /**
     * 根据订单号查询订单信息
     *
     * @param sheinOpenApiSecret
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    @RedisLock(key = "'mesApi:queryProduceOrderInfoById'", waitTime = 60000)
    public QueryProduceOrderInfoByIdResDTO queryProduceOrderInfoById(SysSheinOpenApiSecret sheinOpenApiSecret, QueryProduceOrderInfoByIdReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/query-produce-order-info-by-id", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("根据订单号:{}查询订单信息 接口调用失败,异常原因为：{}", reqDTO.getProduceOrderId(), apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.convert(QueryProduceOrderInfoByIdResDTO.class, apiResult.getInfo());
    }

    /**
     * MES-FAC-005 大货bom接口
     *
     * @param sheinOpenApiSecret
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    @RedisLock(key = "'mesApi:getBigGoodsBom'", waitTime = 60000)
    public GetBigGoodsBomResDTO getBigGoodsBom(SysSheinOpenApiSecret sheinOpenApiSecret, GetBigGoodsBomReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/get-big-goods-bom", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("MES-FAC-005 大货bom接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.convert(GetBigGoodsBomResDTO.class, apiResult.getInfo());
    }

    /**
     * MES-FAC-004 二次工艺接口
     *
     * @param sheinOpenApiSecret
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    public List<GetSecondPrecessResDTO> getSecondPrecess(SysSheinOpenApiSecret sheinOpenApiSecret, GetSecondPrecessReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/get-second-precess", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("MES-FAC-004 二次工艺接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.toList(GetSecondPrecessResDTO.class, apiResult.getInfo());
    }

    /**
     * MES-FAC-002 采购信息接口
     *
     * @param sheinOpenApiSecret
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    public List<GetPurchaseInfoResDTO> getPurchaseInfo(SysSheinOpenApiSecret sheinOpenApiSecret, GetPurchaseInfoReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/get-purchase-info", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("MES-FAC-002 采购信息接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.toList(GetPurchaseInfoResDTO.class, apiResult.getInfo());
    }

    /**
     * 查询发货单信息 接口
     *
     * @param sheinOpenApiSecret
     * @param reqDTO
     * @return
     */
    @SneakyThrows
    @Override
    public List<QueryDeliverOrderResDTO> queryDeliverOrder(SysSheinOpenApiSecret sheinOpenApiSecret, QueryDeliverOrderReqDTO reqDTO) {
        RequestBuilder requestBuilder = this.buildBaseRequestBuilder("/open-api/mes/deliver-order/list", reqDTO, SignModeEnum.OPEN_KEY_ID, sheinOpenApiSecret);
        String response = api.post(requestBuilder);
        ApiResult apiResult = JSON.parseObject(response, new TypeReference<ApiResult>() {
        });
        if (!Objects.equals(apiResult.getCode(), "0")) {
            // 调用失败
            log.error("查询发货单信息接口调用失败,异常原因为：{}", apiResult.getMsg());
            throw new BusinessException(apiResult.getMsg());
        }
        return Convert.toList(QueryDeliverOrderResDTO.class, apiResult.getInfo());
    }

    /**
     * 构建基础的请求对象
     *
     * @param url
     * @param body
     * @param signMode
     * @return
     */

    private RequestBuilder buildBaseRequestBuilder(String url,
                                                   Object body,
                                                   SignModeEnum signMode,
                                                   SysSheinOpenApiSecret openApiSecret) {
        RequestBuilder requestBuilder = new RequestBuilder();
        requestBuilder.setUrl(url);
        requestBuilder.setMethod(HttpMethodEnum.POST);
        requestBuilder.setBody(JSON.toJSONString(body));
        AuthInfo authInfo = AuthInfo.buildAuthInfo(signMode)
                .withAppid(openApiSecret.getAppId())
                .withOpenKeyId(openApiSecret.getOpenKeyId())
                .withAppSecret(openApiSecret.getAppSecret())
                .withSecretKey(openApiSecret.getSecretKey());
        requestBuilder.setAuthInfo(authInfo);
        return requestBuilder;
    }
}
